<!-- Copyright 2014 Google Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// -->
<!DOCTYPE html>
<title>Fast multiplication table</title>
<script src="../../../../closure/base.js"></script>
<script src="../../deps.js"></script>
<script>
  goog.require('goog.Uri');
  goog.require('goog.array');
  goog.require('goog.dom');
  goog.require('e2e.ecc.DomainParam');
  goog.require('e2e.ecc.PrimeCurve');
</script>
<script>

/**
 * Gets the curve whose table we are generating.
 * @return {string} curve
 */
function getCurve() {
  var query = new goog.Uri.QueryData(window.location.search.substr(1));
  var size = query.get('curve', '256');
  if (size.indexOf('256') >= 0) {
    return e2e.ecc.PrimeCurve.P_256;
  } else if (size.indexOf('384') >= 0) {
    return e2e.ecc.PrimeCurve.P_384;
  } else if (size.indexOf('521') >= 0) {
    return e2e.ecc.PrimeCurve.P_521;
  } else {
    return undefined;
  }
}


/**
 * Returns the path to this page.
 * @return {string} The path to this page.
 */
function getPath() {
  var URI = document.documentURI;
  var suffixIndex = URI.lastIndexOf('javascript');
  var path = URI.slice(suffixIndex);
  return path;
}

/**
 * Outputs a fast multiplication table to the document.
 * The opening and closing square are output by the calling code.
 *
 * @param {!Array.<!Array.<e2e.ecc.point.Point>> } table
 */
function outputFastMultiplyTable(table) {
  document.writeln('e2e.ecc.constant.', curve.toLowerCase(),
                   '.G_FAST_MULTIPLY_TABLE = [');
  for (var power = 0; power < table.length; power++) {
    document.writeln('  [');
    for (var i = 0; i < table[power].length; i++) {
      var suffix = (i == table[power].length - 1) ? '' : ',';
      var entry = table[power][i];
      if (entry.isInfinity()) {
        document.writeln('    null', suffix);
      } else {
        document.writeln('    [ //  ', i, ' * (16 ** ', power, ') * G');
        outputBignum(entry.getX().toBigNum(), '      ', ',');
        outputBignum(entry.getY().toBigNum(), '      ', '');
        document.writeln('    ]', suffix);
      }
    }
    document.writeln('  ]', (power == table.length - 1) ? '' : ',');
  }
  document.writeln('];');
}


/**
 * Writes a bignum to the document.  Each line should be preceeded by
 * the specified indent, and the final line should have the finalSuffix
 * appended at the end.
 *
 * @param {e2e.BigNum} b to write
 * @param {string} indent indent to put at the start of each line
 * @param {string} finalSuffix closing for final line
 */
function outputBignum(b, indent, finalSuffix) {
  var result = [];
  for (var i = 0; i < b.n.length; i += 6) {
    var piece = goog.array.slice(b.n, i, Math.min(i + 6, b.n.length));
    result.push(piece.join(', '));
  }
  for (var i = 0; i < result.length; i++) {
    var prefix = ((i == 0) ? '[' : ' ');
    var suffix = ((i == result.length - 1) ? ']' + finalSuffix : ',');
    document.writeln(indent, prefix, result[i], suffix);
  }
}

// Get the curve
var curve = getCurve();
var params = e2e.ecc.DomainParam.fromCurve(curve);
var table = params.g.createFastMultiplyTable();
</script>
<span id="GeneratedOutput">
<pre>
/**
<script>
document.write(' * @fileoverview Precomputed powers of the ',
               curve, ' generator point.');
</script>
 *
 * This file was generated by looking at the document
<script>
document.write(' *   ', getPath());
</script>
 * in a web browser, and then copying its output.
 *
 * THIS IS A GENERATED FILE.  DO NOT MODIFY.
<script>
document.write(' * Generated: ', new Date());
</script>
 *
 * @author fy@google.com (Frank Yellin)
 */

<script>
document.writeln('goog.provide(\'e2e.ecc.constant.',
               curve.toLowerCase(), '.G_FAST_MULTIPLY_TABLE\');');
</script>

/**
 *
 * The value of G_FastMultiply[i][j] gives the value of
 *     ((16 ** i) * j) * G
 * where G is the NIST-specified point that is a generator for the
<script>
document.write(' * ', curve, ' curve.');
</script>
 *
 * Each non-infinite point is represented as [X, Y], where X and Y
 * each represent a bignum as a base 2**24 array of integers in little-endian
 * order.  The point at infinity is represented by {@code null}.
 *
 * @type {!Array.&lt;!Array.&lt;Array.&lt;!Array.&lt;!number&gt;&gt;&gt;&gt;}
 */
<script>
// At some time in the future, we'll have a BUILD rule that can pull the
// generated table from a headless browser using
//    document.documentElement.innerText;
// For now, the output from loading this file needs to be cut and pasted
// from a real browser.
if (goog.isDef(table)) {
  outputFastMultiplyTable(table);
} else {
  document.writeln('<h1>Unknown or unimplemented curve!</h1>');
}
</script>
</pre></span>
